<?php


namespace api\controller;

use common\controller\VerifyController;
use common\exception\LogicException;
use common\service\OrderService;
use common\service\ReviewTaskService;
use common\validate\Order;
use support\bootstrap\Redis;
use support\ErrorCode;
use think\Exception;
use think\Request;
use Webman\Stomp\Client;

class OrderController extends VerifyController
{

    /** @var OrderService */
    protected $orderService;
    /**
     * @var ReviewTaskService
     */
    private $reviewTaskService;

    public function __construct()
    {
        parent::__construct();
        $this->orderService = OrderService::getInstance();
        $this->reviewTaskService = ReviewTaskService::getInstance();
    }

    /**
     * 提交订单
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     */
    public function create(Request $request)
    {
        $param = $request->param();

        // 防止同一时间,一个任务创建多个订单,并发阻止
        $tenantId = $request->tenantId;
        $userId = $request->userId;

        // create lock
        $lockKey = 'lock_order_create:' . 'tenant_id:' . $tenantId . 'user_id:' . $userId;
        if (Redis::get($lockKey)) {
            throw_strack_exception("order create is currently in progress", ErrorCode::CREATE_ORDER_IS_CURRENTLY_IN_PROGRESS);
        } else {
            Redis::setEx($lockKey, 5, $lockKey);
        }

        $validator = new Order();
        foreach ($param['data'] as $order) {
            $validator->scene("Order");
            if (!$validator->check($order)) {
                throw_strack_exception($validator->getError(), ErrorCode::ORDER_CREATE_BASE_PARAM);
            }
            foreach ($order['task_list'] as $taskList) {
                $validator->scene("OrderTaskList");
                if (!$validator->check($taskList)) {
                    throw_strack_exception($validator->getError(), ErrorCode::ORDER_CREATE_TASK_LIST_PARAM);
                }
            }
        }

        try {
            $res = $this->orderService->create($param['data']);
            return json(success_response('', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 修改订单
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     */
    public function updateOrder(Request $request)
    {
        $param = $request->param();
        if (array_key_exists('task_list', $param['data'])) {
            $validator = new Order();
            $validator->scene('UpdateOrderTaskList');
            foreach ($param['data']['task_list'] as $taskItem) {
                if (!$validator->check($taskItem)) {
                    throw_strack_exception($validator->getError(), ErrorCode::ORDER_UPDATE_TASK_LIST_PARAM);
                }
            }
        }

        try {
            $res = $this->orderService->update($param['data'], $request->getUserId());
            return json(success_response('', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 订单列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getOrderList(Request $request)
    {
        $param = $request->param()['param'];
        $param['type'] = $type = $param['type'] ?? 0;

        $filterTenantKey = "`order`.from_tenant_id";
        if ($type == 1) {
            $filterTenantKey = "`order`.to_tenant_id";
        }
        $param['filter'] = $param['filter'] ?? [];
        $param['filter'][$filterTenantKey] = auto_fill_tenant_id();
        $res = $this->orderService->getOrderList($param, auto_fill_tenant_id());
        return json(success_response('', $res));
    }

    /**
     * 订单详情
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getOrderDetail(Request $request)
    {
        $param = $request->param();
        $res = $this->orderService->getOrderDetail($param['param'], $request->getTenantId());
        return json(success_response('', $res));
    }

    /**
     * 乙方确认订单
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     */
    public function partyBAcceptOrder(Request $request)
    {
        $res = $this->orderService->partyBAcceptOrder($request->param(), $request->getUserId(), $request->param()['party_b_resp_producer_id'], $request->getTenantId());
        return json(success_response('', $res));
    }

    /**
     * 乙方操作订单
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     * @throws \think\Exception
     */
    public function partyBHandleOrder(Request $request)
    {
        $res = $this->orderService->partyBHandleOrder($request->param(), $request->getUserId(), $request->getTenantId());
        return json(success_response('', $res));
    }

    /**
     * 待审核订单统计
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getMyReviewOrderCount(Request $request)
    {
        $res = $this->orderService->getMyReviewOrderCount();
        return json(success_response('', $res));
    }

    /**
     * 待审核订单列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getMyReviewOrderList(Request $request)
    {
        $res = $this->orderService->getMyReviewOrderList($request->param(), $request->getTenantId());
        return json(success_response('', $res));
    }

    /**
     * 待发起结算列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getWaitForAddSettlementOrderList(Request $request)
    {
        $res = $this->orderService->getWaitForAddSettlementOrderList($request->param(), $request->getTenantId());
        return json(success_response('', $res));
    }

    /**
     * 通过更新
     * @param Request $request
     * @return \think\Response
     * @throws \think\Exception
     */
    public function update(Request $request)
    {
        $param = $request->param();
        $res = $this->orderService->commonUpdate($param['data'], $request->getModuleCode());
        return json(success_response('', $res));
    }

    /**
     * 待甲方开票发票订单列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getWaitForApplyInvoiceOrderList(Request $request)
    {
        $param = $request->param();
        $res = $this->orderService->getWaitForApplyInvoiceOrderList($param['param'], auto_fill_tenant_id());
        return json(success_response('', $res));
    }

    /**
     * 生成订单外包文件传输列表(上游依赖文件) 甲方=>乙方
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function generatedOrderTaskFileList(Request $request)
    {
        $param = $request->param();
        $async = $param['param']['is_async'] ?? 'no';
        if ($async === 'yes') {
            Client::send('generate_order_task_file_list', build_queue_data_with_xu(['order_id' => $param['param']['order_id'], 'user_id' => $request->getUserId()]));
            $res = 0;
        } else {
            $res = $this->orderService->generatedOrderTaskFileList($param['param']['order_id'], $request->getUserId());
        }
        return json(success_response('', $res));
    }

    public function cancelOtherSameOrder(Request $request)
    {
        $res = $this->orderService->cancelOtherSameOrder($request->param()['id']);
        return json(success_response('OK', $res));
    }

    /**
     * 生成播放列表
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     */
    public function generatePlaylistPackage(Request $request)
    {
        try {
            $res = $this->orderService->generatePlaylistPackage($request->param()['id']);
            return json(success_response('OK', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 设置集团化工序任务执行人
     * @param Request $request
     * @return \think\Response
     * @throws \Throwable
     */
    public function setTenantGroupStepTaskExecutor(Request $request)
    {
        $this->orderService->setTenantGroupStepTaskExecutor($request->param()['param']['order_id']);
        return json(success_response('OK', []));
    }

    /**
     * 更新订单文件状态
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function updateOrderFileStatus(Request $request)
    {
        try {
            $res = $this->orderService->updateOrderFileStatus($request->param()['id']);
            return json(success_response('OK', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 撤回订单
     * @param Request $request
     * @return \think\Response|void
     */
    public function withdrawn(Request $request)
    {
        try {
            $res = $this->orderService->withdrawn($request->param()['param']['filter']['id']);
            return json(success_response('OK', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 查询订单审核管理列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getOrderTaskReviewList(Request $request)
    {
        $param = $request->param()['param'];
        $res = $this->reviewTaskService->getOrderTaskReviewList($param['order_id'], $param['filter'], $param);
        return json(success_response('OK', $res));
    }

    /**
     * 提交订单任务列表审核
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     * @throws \Throwable
     */
    public function submitOrderTaskListReview(Request $request)
    {
        $data = $request->param()['data'];
        $taskIdList = $data['task_id_list'];
        $orderId = $data['order_id'];
        try {
            $res = $this->reviewTaskService->submitOrderTaskListReview($taskIdList, $orderId);
            return json(success_response('OK', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 乙方处理反馈(接受/拒绝)
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     * @throws \Throwable
     */
    public function partybHandleReviewNote(Request $request)
    {
        try {
            $param = $request->param()['param'];
            $reviewRequestNodeId = $param['review_request_node_id'];
            $accept = $param['accept'] === 'yes';
            if ($accept) {
                $res = $this->reviewTaskService->partybAcceptReviewNote($reviewRequestNodeId);
            } else {
                $res = $this->reviewTaskService->partybDenyReviewNote($reviewRequestNodeId);
            }
            return json(success_response('OK', $res));
        } catch (LogicException $e) {
            throw_strack_exception($e->getMessage(), $e->getCode());
        }
    }

    /**
     * 外包订单查询项目列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getProjectList(Request $request)
    {
        $param = $request->param()['param'];
        $param['type'] = $param['type'] ?? 0;

        $filterTenantKey = "`order`.from_tenant_id";
        if ($param['type'] == 1) {
            $filterTenantKey = "`order`.to_tenant_id";
        }
        $param['filter'] = $param['filter'] ?? [];
        $param['filter'][$filterTenantKey] = auto_fill_tenant_id();
        $res = $this->orderService->getProjectList($param, $filterTenantKey);
        return json(success_response('', $res));
    }

    /**
     * 查询所有的订单审核管理列表
     * @param Request $request
     * @return \think\Response
     * @throws \Exception
     */
    public function getAllOrderTaskReviewList(Request $request)
    {
        $param = $request->param()['param'];
        $res = $this->reviewTaskService->getAllOrderTaskReviewList($request->getTenantId(), $param['filter'], $param);
        return json(success_response('OK', $res));
    }

    /**
     * 获取等待签署的订单
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getWaitForSignOrderList(Request $request)
    {
        $param = $request->param()['param'] ?? [];
        $res = $this->orderService->getWaitForSignOrderList($param, $request->getTenantId());
        return json(success_response('OK', $res));
    }

    /**
     * 当前用户的外包审批
     * @param Request $request
     * @return \think\Response
     * @throws Exception
     */
    public function getMySelfOutsideReviewOrderList(Request $request)
    {
        $param = $request->param()['param'] ?? [];
        $userId = request()->getUserId();
        $res = $this->orderService->getMySelfOutsideReviewOrderList($param, $request->getTenantId(), $userId);
        return json(success_response('OK', $res));
    }

    /**
     * 获取集团公司订单
     * @param Request $request
     * @return \think\Response
     */
    public function getTenantGroupOrder(Request $request)
    {
        $param = $request->param()['param'];
        $res = $this->orderService->getTenantGroupOrder($param);
        return json(success_response('ok', $res));
    }
}
